package com.example.musicrecommend.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.musicrecommend.common.BaseResponse;
import com.example.musicrecommend.common.ErrorCode;
import com.example.musicrecommend.common.ResultUtils;
import com.example.musicrecommend.exception.BusinessException;
import com.example.musicrecommend.exception.ThrowUtils;
import com.example.musicrecommend.model.dto.song.SongQueryRequest;
import com.example.musicrecommend.model.dto.song.SongRecommendRequest;
import com.example.musicrecommend.model.dto.song.SongSearchRequest;
import com.example.musicrecommend.model.vo.SongVO;
import com.example.musicrecommend.service.SongService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;


@RestController
@RequestMapping("/song")
@Slf4j
public class SongController {


    //TODO: temp test
    private final String SongFilesPathRoot = "D:\\CloudMusic\\";

    @Resource
    private SongService songService;



    /**
     * 根据 id 获取Song
     *
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/get/{id}")
    public BaseResponse<SongVO> getSongById(@PathVariable Long id, HttpServletRequest request) {
        ThrowUtils.throwIf(id<=0,ErrorCode.PARAMS_ERROR);

        SongVO songVO = songService.getSongById(id);

        ThrowUtils.throwIf(songVO == null, ErrorCode.NOT_FOUND_ERROR);

        return ResultUtils.success(songVO);
    }

    /**
     * 分页获取song列表
     *
     * @param songQueryRequest
     * @param request
     * @return
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<SongVO>> listSongByPage(SongQueryRequest songQueryRequest,
                                                       HttpServletRequest request) {
        long current = songQueryRequest.getCurrent();
        long size = songQueryRequest.getPageSize();
        Page<SongVO> songPage =songService.selectSongsPage(new Page<>(current, size),
                songService.getQueryWrapper(songQueryRequest));
        return ResultUtils.success(songPage);

    }

    @PostMapping("/recommend")
    public BaseResponse<List<SongVO>> recommendSongs(SongRecommendRequest songRecommendRequest,HttpServletRequest request) {
        long userId = songRecommendRequest.getUserId();
        long limit = songRecommendRequest.getLimit();

        // run python script
        String batPath = "D:/JavaProjects/music-recommend/gtzan.keras/recommender.bat";

        String result = null;
        try {
            ProcessBuilder pb = new ProcessBuilder(batPath,"-i",""+userId,"-n",""+limit);
            Process process = pb.start();

            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(),"utf-8"));
            String line;
            while ((line= reader.readLine())!=null) {
                log.info(line);
                result=line;
            }
            reader.close();
            int exitCode = process.waitFor();

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        if (result != null) {
            String[] songIds = result.split(",");
            List<SongVO> ret = new ArrayList<>();
            for(String id : songIds) {
                SongVO one = songService.getSongById(id);
                ret.add(one);
            }
            return ResultUtils.success(ret);
        }
        else {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }

    }

    /**
     * search模糊搜索并分页获取
     *
     * @param songSearchRequest
     * @param request
     * @return
     */
    @GetMapping("/search")
    public BaseResponse<Page<SongVO>> searchSongByPage(SongSearchRequest songSearchRequest,
                                                       HttpServletRequest request) {
        long current = songSearchRequest.getCurrent();
        long size = songSearchRequest.getPageSize();
        Page<SongVO> songPage =songService.selectSongsPage(new Page<>(current, size),
                songService.getQueryWrapper(songSearchRequest));
        return ResultUtils.success(songPage);
    }



    //TODO: ??;
    //music file download
    @GetMapping("/file/{url}")
    public ResponseEntity<org.springframework.core.io.Resource> getSongFile(@PathVariable String url){

        Path filePath = Paths.get(SongFilesPathRoot).resolve(url).normalize();

        try {
            org.springframework.core.io.UrlResource resource = new org.springframework.core.io.UrlResource(filePath.toUri());
            if (resource.exists() || resource.isReadable()) {
                return ResponseEntity.ok()
                        .contentType(MediaType.APPLICATION_OCTET_STREAM)
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
                        .body(resource);
            } else {
                return ResponseEntity.notFound().build();
            }
        } catch (IOException ex) {
            log.error(ex.toString());
            return ResponseEntity.status(500).build();
        }
    }


/* /file-v1/{url}
    @GetMapping("/file-v1/{url}")
    public void getSongFileV1(@PathVariable String url, HttpServletRequest request, HttpServletResponse response) {

        File file = new File(SongFilesPathRoot + url);

        if (!file.exists() || !file.isFile()) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR,"文件不存在或不是文件");
        }

        String fileName = file.getName();
        String contentType = request.getServletContext().getMimeType(fileName);
        response.setContentType(contentType);

        response.setHeader("Content-Disposition", "inline;filename="+fileName);
        response.setStatus(200);


        try {
            // 读取文件内容
            byte[] buff = Files.readAllBytes(file.toPath());
            BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            outputStream.write(buff,0,buff.length);
            outputStream.flush();
            response.flushBuffer();

            log.info("下载完毕,name: "+ fileName+",length: " + buff.length);


        } catch (IOException e) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR,"读取文件失败");
        }

    }
*/





}

